package io.mft.commons.db.metadata;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.hutool.db.Entity;
import io.mft.commons.db.mapper.TableDbMapper;
import io.mft.commons.db.source.DbProvider;

public  class TableColumnMetadata {

	private static Map<String, TableMap> map = new HashMap<>();

	
	private static final Logger log = LoggerFactory.getLogger(TableColumnMetadata.class);

	public static TableMap getTableMap(String datasourceId) {
		return map.get(datasourceId);
	}
	  public static void startInitToMemory() {
		   initToMemory();
			Executors.newSingleThreadExecutor().execute(new Runnable() {
				
				@Override
				public void run() {
					try {
						 while (true) {
							 try {
								 TimeUnit.SECONDS.sleep(5);
								 initToMemory();
							} catch (Exception e) {
								log.error("",e);
							}
						}
					} catch (Exception e) {
						log.error("",e);
					}
					
				}
			});
		}
	public static ColumnMeta getColumnMeta(String datasourceId,String tableName,String columnName) {
		ColumnMeta columnMeta=null;
		TableMap tableMap=map.get(datasourceId);
		if (tableMap!=null) {
			Table table=tableMap.get(tableName);
			if (table!=null) {
				columnMeta=table.get(columnName);
			}
		}
		return columnMeta;
	}

	private static void initToMemory() {
		DbProvider.getInstance().getDatasourceIdList().forEach(a->{
			try {
				initToMemory(a);
			} catch (Exception e) {
				log.error("",e);
			}
			
		});
	}
	private static void initToMemory(String datasourceId) throws SQLException {
		TableDbMapper<ColumnMeta> mapper = TableDbMapper.getInstance(datasourceId, "information_schema.COLUMNS",ColumnMeta.class);
		TableDbMapper<Entity> tableMapper = TableDbMapper.getInstance(datasourceId, "information_schema.TABLES",Entity.class);
		TableMap tableMap=map.get(datasourceId);
		if (tableMap==null) {
			tableMap=new TableMap();
			map.put(datasourceId, tableMap);
		}
		String tableSchema=DbProvider.getInstance().dbSchema(datasourceId);
		List<ColumnMeta> columnMetas=mapper.find("tableSchema",tableSchema);
		for (ColumnMeta columnMeta : columnMetas) {
			Table table=tableMap.get(columnMeta.getTableName());
			if (table==null) {
				table=new Table();
				Entity where=new Entity();
				where.set("tableSchema", tableSchema);
				where.set("tableName", columnMeta.getTableName());
				Entity tbEntity=tableMapper.get(where, true);
				table.setTableName(columnMeta.getTableName());
				table.setTableSchema(tableSchema);
				table.setTableComment(tbEntity.getStr("tableComment"));
				tableMap.put(columnMeta.getTableName(), table);
			}
			table.put(columnMeta.getColumnName(), columnMeta);
		}
	}
}
